package com.example.springboothomework.service.impl;

import com.example.springboothomework.common.PageResponse;
import com.example.springboothomework.dao.CompanyDao;
import com.example.springboothomework.dao.EmployeeDao;
import com.example.springboothomework.entity.Company;
import com.example.springboothomework.entity.dto.CompanyDTO;
import com.example.springboothomework.entity.vo.CompanyInfoVo;
import com.example.springboothomework.exception.BusinessException;
import com.example.springboothomework.exception.ResultCodeEnum;
import com.example.springboothomework.mapper.CompanyMapper;
import com.example.springboothomework.service.ICompanyService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.util.List;

/**
 * 公司service接口实现类
 *
 * @author chenjianhao
 * @date 2025/6/6
 */
@Service
@RequiredArgsConstructor
public class CompanyServiceImpl implements ICompanyService {

    private final CompanyDao companyDao;
    private final EmployeeDao employeeDao;
    private final CompanyMapper companyMapper;

    /**
     * 添加公司
     * @param companyDTO
     * @return
     */
    @Override
    public Long save(CompanyDTO companyDTO) {
        //公司是否同名
        if (companyDao.existsByName(companyDTO.getName())) {
            throw new BusinessException(ResultCodeEnum.COMPANY_NAME_EXIST);
        }

        //添加公司
        Company company = companyMapper.toEntity(companyDTO);
        companyDao.save(company);
        return company.getId();
    }

    /**
     * 删除公司
     * @param id
     * @return
     */
    @Override
    public void delete(Long id) {
        //公司是否存在
        if (!companyDao.existsById(id)) {
            throw new BusinessException(ResultCodeEnum.COMPANY_NOT_EXITS);
        }
        //公司是否存在员工
        if (employeeDao.existsByCompanyId(id)) {
            throw new BusinessException(ResultCodeEnum.COMPANY_EMPLOYEE_EXIST);
        }
        //删除公司
        companyDao.deleteById(id);
    }

    /**
     * 更新公司
     * @param companyDTO
     * @return
     */
    @Override
    public void update(CompanyDTO companyDTO) {
        //公司是否存在，在则查出
        Company company = companyDao.findById(companyDTO.getId())
                .orElseThrow(() -> new BusinessException(ResultCodeEnum.COMPANY_NOT_EXITS));

        /**
         * 修改前和修改后是否同名
         * 且是否依旧存在同名的公司
         */
        if (!companyDTO.getName().equals(company.getName()) && 
            companyDao.existsByName(companyDTO.getName())) {
            throw new BusinessException(ResultCodeEnum.COMPANY_NAME_EXIST);
        }

        //更新公司信息
        companyMapper.updateEntity(companyDTO, company);
        companyDao.save(company);
    }

    /**
     * 通过id获得公司
     * @param id
     * @return
     */
    @Override
    public Company info(Long id) {
        return companyDao.findById(id)
                .orElseThrow(() -> new BusinessException(ResultCodeEnum.COMPANY_NOT_EXITS));
    }

    /**
     * 分页查询公司 jpa-spec
     *
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public PageResponse<Company> queryPage(Integer pageNum, Integer pageSize, String keyword) {
        //分页初始化
        int pNum = (pageNum == null || pageNum < 1) ? 1 : pageNum;
        int pSize = (pageSize == null || pageSize < 1) ? 10 : pageSize;
        // 构建查询条件
        Specification<Company> spec = (root, query, criteriaBuilder) -> {
            Predicate namePredicate = null;
            if (keyword != null && !keyword.isEmpty()) {
                namePredicate = criteriaBuilder.like(root.get("name"), "%" + keyword + "%");
            }
            return namePredicate;
        };
        Pageable pageable = PageRequest.of(pNum - 1, pSize, Sort.by(Sort.Direction.DESC, "establishmentDate"));
        Page<Company> page = companyDao.findAll(spec, pageable);
        return new PageResponse<>(
                pNum,
                pSize,
                page.getTotalElements(),
                page.getContent()
        );
    }

    /**
     * 获得所有公司基本信息（id+name）
     * @return
     */
    @Override
    public List<CompanyInfoVo> getAllIdAndName() {
        return companyDao.findAllCompanyInfo();
    }
}